﻿// NFakeMail - A fake SMTP Server for software testing.
// 
// Copyright (C) 2010, João Angelo
// 
// This file is part of NFakeMail.
//
// NFakeMail is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
// 
// NFakeMail is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
// 
// You should have received a copy of the GNU General Public License
// along with NFakeMail; if not, see <http://www.gnu.org/licenses/>.

namespace NFakeMail
{
    using System;
    using System.Collections.Generic;
    using System.Net;
    using System.Net.Mail;

    /// <summary>
    /// Represents a mail message received by the fake SMTP server.
    /// </summary>
    /// <author> jmangelo </author>
    /// <history>
    /// ______________________________________________________________________________________
    /// History :
    /// 20100816 [+] jmangelo     Initial version
    /// ______________________________________________________________________________________
    /// </history>
    public sealed class FakeMailMessage
    {
        private string subject;

        internal FakeMailMessage(
            string clientAddress,
            int clientPort,
            string from,
            IEnumerable<string> to,
            string msg)
        {
            IPAddress clientIPAdress;
            if (!IPAddress.TryParse(clientAddress, out clientIPAdress))
            {
                clientIPAdress = IPAddress.Any;
            }

            this.Client = new IPEndPoint(clientIPAdress, clientPort);
            this.From = new MailAddress(from);

            this.Recipients = new MailAddressCollection();

            foreach (var mailAddress in to)
            {
                this.Recipients.Add(mailAddress);
            }

            this.MimeMessage = msg;
        }

        /// <summary>
        /// Gets the IP address information for the client that sent this message.
        /// </summary>
        /// <value>The IP address information of the client that sent the message.</value>
        public IPEndPoint Client { get; private set; }

        /// <summary>
        /// Gets the from mail address.
        /// </summary>
        /// <value>The from mail address.</value>
        public MailAddress From { get; private set; }

        /// <summary>
        /// Gets the list of addresses of the message recipients.
        /// </summary>
        /// <value>The list of addresses of the message recipients.</value>
        public MailAddressCollection Recipients { get; private set; }

        /// <summary>
        /// Gets the subject of the message.
        /// </summary>
        /// <value>The message subject.</value>
        public string Subject
        {
            get
            {
                if (this.subject == null)
                {
                    this.Subject = GetMailMessageSubject(this.MimeMessage);
                }

                return this.subject;
            }

            set
            {
                this.subject = value;
            }
        }

        /// <summary>
        /// Gets the raw MIME message as received by the server.
        /// </summary>
        /// <value>The raw MIME message.</value>
        public string MimeMessage { get; private set; }

        private static string GetMailMessageSubject(string mimeMessage)
        {
            const string SubjectHeaderFieldName = "Subject";

            string mimeHeadersSection = MimeUtils.GetHeadersSection(mimeMessage);

            string subjectHeaderValue = MimeUtils.GetHeaderValue(
                SubjectHeaderFieldName, 
                mimeHeadersSection);

            return MimeUtils.DecodeMimeEncodedWords(subjectHeaderValue);
        }
    }
}
